package com.lbc.service.impl;

import com.lbc.bean.dto.*;
import com.lbc.bean.entity.Organization;
import com.lbc.bean.entity.Role;
import com.lbc.bean.entity.School;
import com.lbc.bean.entity.User;
import com.lbc.bean.vo.*;
import com.lbc.common.constants.Constants;
import com.lbc.common.enums.RoleEnum;
import com.lbc.common.exception.CustomException;
import com.lbc.common.utils.JwtUtils;
import com.lbc.common.utils.RandomUtil;
import com.lbc.dao.custom.*;
import com.lbc.dao.generator.RoleMapper;
import com.lbc.service.UserService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author xyl
 * @date 2021-03-03 10:23
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private CtUserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private CtOrganizationMapper organizationMapper;
    @Autowired
    private CtSchoolMapper schoolMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private CtKidAssistMapper kidAssistMapper;
    @Autowired
    private CtKidMapper kidMapper;

    @Override
    public User getUserById(Integer userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    @Override
    public List<String> getRolesByUserId(Integer userId) {
        User user = this.getUserById(userId);
        Role role = roleMapper.selectByPrimaryKey(user.getRoleId());
        List<String> list = new ArrayList<>();
        list.add(role.getRoleKey());
        return list;
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public User getUserByEmail(String email) {
        return userMapper.selectByEmail(email);
    }

    @Async("taskExecutor")
    @Override
    public void sendMail(String mail, String key) {
        SimpleMailMessage message = new SimpleMailMessage();
        String verifyCode = RandomUtil.generateVerifyCode(6);
        message.setTo(mail);
        //谁发的，发件人的邮箱，也就是你的邮箱
        message.setFrom(Constants.SEND_EMAIL);
        //邮件标题-自定义
        message.setSubject("你的注册验证码");
        message.setText("验证码:" + verifyCode);
        //设置十分钟过去
        stringRedisTemplate.opsForValue().set(key, verifyCode, 10, TimeUnit.MINUTES);
        try {
            mailSender.send(message);
        } catch (MailException e) {
            e.printStackTrace();
        }
    }

    @Override
    public int add(User user) {
        user.setCreateTime(new Date());
        //0是  自己注册的
        user.setCreateBy(0);
        user.setState(Constants.USER_STATE1);
        user.setRoleId(RoleEnum.ROLE_USER.getType());
        return userMapper.insertSelective(user);
    }

    @Override
    public UserVO getUserVOById(Integer userId) {
        UserVO userVO = userMapper.selectUserVOById(userId);
        userVO.setRoles(Collections.singletonList(userVO.getRole()));
        return userVO;
    }

    @Override
    public int resetPassword(ResetPasswordDTO resetPasswordDTO) {
        return userMapper.updateByEmail(resetPasswordDTO);
    }

    @Override
    public int adminAddUser(AdminAddUserDTO userDTO) {
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setCreateTime(new Date());
        //1是  管理员添加的
        user.setCreateBy(1);
        user.setState(Constants.USER_STATE1);
        return userMapper.insertSelective(user);
    }

    @Override
    public int modifyUserState(Integer userId, Integer state) {
        return userMapper.updateUserState(userId, state);
    }

    @Override
    public List<UserVO> getUserList(Integer roleId, Integer state, String searchKey) {
        List<UserVO> list = userMapper.selectUser(roleId, state, searchKey);
        list.forEach(user -> user.setRoles(Collections.singletonList(user.getRole())));
        return list;
    }

    //    @Async("taskExecutor")
    @Override
    public int modifyUserLastLoginTime(Integer userId, Date lastLoginTime) {
        return userMapper.updateLastLoginTimeById(userId, lastLoginTime);
    }

    @Override
    public List<RoleVO> selectRoleCount() {
        return userMapper.selectRoleCount();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int adminRemoveUser(Integer userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (Constants.ROLE_ORGANIZATION == user.getRoleId()) {
            //获取帮扶机构
            Organization o = organizationMapper.selectByUserId(userId);
            //删除帮扶记录
            int count = kidAssistMapper.deleteByOrgId(o.getOrganizationId());
            //删除机构信息
            int i = organizationMapper.deleteByPrimaryKey(o.getOrganizationId());
            //删除用户
            int u = userMapper.deleteByPrimaryKey(userId);
        } else if (Constants.ROLE_SCHOOL == user.getRoleId()) {
            //修改儿童关联
            int count1 = kidMapper.updateSchoolIdToNull(userId);
            //删除用户信息
            int count2 = userMapper.deleteByPrimaryKey(userId);
        }
        return 1;
    }

    @Override
    public int getRoleIdByUserId(Integer userId) {
        return userMapper.selectRoleIdByUserId(userId);
    }

    @Override
    public List<UserIdAndNameVO> getSchoolAll() {
        return schoolMapper.selectSchoolAll();
    }

    @Override
    public List<UserIdAndNameVO> getOrganizationAll() {
        return organizationMapper.selectOrganizationAll();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int adminAddOrganization(OrganizationDTO organization) {
        User user = new User();
        user.setRoleId(Constants.ROLE_ORGANIZATION);
        BeanUtils.copyProperties(organization, user);
        user.setCreateTime(new Date());
        user.setCreateBy(JwtUtils.getUserId());
        user.setUsername(organization.getOrgName());
        user.setState(1);
        int insert = userMapper.insert(user);
        Organization org = new Organization();
        BeanUtils.copyProperties(organization, org);
        org.setCreateTime(new Date());
        org.setCreateBy(JwtUtils.getUserId());
        org.setUserId(user.getUserId());
        int insert1 = organizationMapper.insert(org);
        return insert + insert1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int adminAddSchool(SchoolDTO school) {
        User user = new User();
        BeanUtils.copyProperties(school, user);
        user.setCreateTime(new Date());
        user.setCreateBy(JwtUtils.getUserId());
        user.setUsername(school.getSchoolName());
        user.setRoleId(Constants.ROLE_SCHOOL);
        user.setState(1);
        int insert = userMapper.insert(user);

        School sch = new School();
        BeanUtils.copyProperties(school, sch);
        sch.setCreateTime(new Date());
        sch.setCreateBy(JwtUtils.getUserId());
        sch.setUserId(user.getUserId());
        int insert1 = schoolMapper.insert(sch);
        return insert + insert1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int adminModifySchool(SchoolDTO school) {
        School temp = schoolMapper.selectBySchoolId(school.getSchoolId());
        if (ObjectUtils.isEmpty(temp)) {
            CustomException.cast("id参数有误！");
        }
        School sch = new School();
        BeanUtils.copyProperties(school, sch);
        sch.setUpdateTime(new Date());
        sch.setUpdateBy(JwtUtils.getUserId());
        sch.setSchoolId(temp.getSchoolId());
        int i = schoolMapper.updateByPrimaryKeySelective(sch);

        User user = new User();
        BeanUtils.copyProperties(school, user);
        user.setUserId(temp.getUserId());
        user.setUpdateTime(new Date());
        user.setUpdateBy(JwtUtils.getUserId());
        int insert = userMapper.updateByPrimaryKeySelective(user);
        return insert;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int adminModifyOrganization(OrganizationDTO dto) {
        Organization temp = organizationMapper.selectByPrimaryKey(dto.getOrgId());
        if (ObjectUtils.isEmpty(temp)) {
            CustomException.cast("未找到对应orgId");
        }
        Organization organization = new Organization();
        BeanUtils.copyProperties(dto, organization);
        organization.setOrganizationId(dto.getOrgId());
        organization.setUpdateBy(JwtUtils.getUserId());
        organization.setUpdateTime(new Date());
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setUserId(temp.getUserId());
        user.setUpdateTime(new Date());
        user.setUpdateBy(JwtUtils.getUserId());
        user.setRoleId(Constants.ROLE_ORGANIZATION);
        int i1 = organizationMapper.updateByPrimaryKeySelective(organization);
        int i = userMapper.updateByPrimaryKeySelective(user);
        return i + i1;
    }

    @Override
    public SchoolInfoVO getMySchoolInfo(Integer userId) {
        SchoolInfoVO schoolInfoVO = schoolMapper.selectByUserId(userId);
        schoolInfoVO.setRoles(Collections.singletonList(schoolInfoVO.getRole()));
        return schoolInfoVO;
    }

    @Override
    public OrganizationInfoVO getMyOrganizationInfo(Integer userId) {
        OrganizationInfoVO organizationInfoVO = organizationMapper.selectInfoByUserId(userId);
        organizationInfoVO.setRoles(Collections.singletonList(organizationInfoVO.getRole()));
        return organizationInfoVO;
    }

    @Override
    public int adminModifyParent(ParentDTO parent) {
        User user = new User();
        BeanUtils.copyProperties(parent, user);
        return userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public List<OrganizationPageVO> getOrganizationPage(String searchKey) {
        List<OrganizationPageVO> list = organizationMapper.selectPageList(searchKey);
        return list;
    }

    @Override
    public List<SchoolPageVO> getSchoolPage(String searchKey) {
        return schoolMapper.selectPageList(searchKey);
    }
}
